package com.alison.SmartCli;

import com.alison.SmartCli.BuiltInFunction.BuiltInManager;
import com.alison.SmartCli.Utils.ReflectionUtil;
import com.alison.SmartCli.Utils.TypeCaster;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 管理自定义方法
 */
class MethodManager {

    private BeanFactory beanFactory;

    MethodManager(){
        this.beanFactory = new DefaultBeanFactory();
    }

    MethodManager(BeanFactory factory){
        this.beanFactory = factory;
    }

    void invoke(String name,String[] args){
        if (isUserDefineFunction(name)){
            executeUserFunction(name, args);
        }else if (isBuiltInFunction(name)){
            executeBuiltInFunction(name,args);
        }else{
            System.out.println("不存在方法："+name);
        }
    }

    private boolean isUserDefineFunction(String methodName){
        return MethodData.containUserMethod(methodName);
    }

    private boolean isBuiltInFunction(String methodName){
        return BuiltInManager.isBuiltInFunction(methodName);
    }

    private void executeBuiltInFunction(String methodName,String[] args){
        BuiltInManager.invokeBuiltInFunction(methodName, args);
    }

    private void executeUserFunction(String methodName,String[] args){
        //解析命令
        Method method = MethodData.getMethod(methodName);
        if (method == null){
            return;
        }
        Object target = beanFactory.getBean(MethodData.getMethodClass(methodName));
        try {
            Parameter[] parameters = method.getParameters();
            List<Object> params = parseParameter(parameters,args);
            Object res = method.invoke(target,params.toArray());
            if (res!=null){
                System.out.println(res);
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }



    private List<Object> parseParameter(Parameter[] parameters,String[] args){
        List<Object> target  = new ArrayList<>();
        int methodParamsLen = parameters.length;
        int argsLen = args.length;
        int len = methodParamsLen>argsLen? argsLen : methodParamsLen;
        //如果参数不足，后面补null
        for(int i=0;i<len;i++){
            Parameter param = parameters[i];
            String value = args[i];
            target.add(TypeCaster.cast(param,value));
        }
        for (int i=0;i<methodParamsLen - len;i++){
            target.add(null);
        }
        return target;
    }




}
